package com.cool.collect.swaputils;

import com.cool.collect.swaputils.annotation.IgnoreSwap;

import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;

/**
 * @Author: xiemiao
 * @CreateTime: 2023-05-18  09:45
 * @Description: TODO
 * @Version: 1.0
 */
public class SwapUtil {
    /**
     * 交换两个对象的属性值
     *
     * @param obj1             第一个对象
     * @param obj2             第二个对象
     * @param ignoreProperties 忽略交换的属性
     */
    public static void swapProperties(Object obj1, Object obj2, String[] ignoreProperties) {
        Class<?> clazz = obj1.getClass();
        Field[] fields = clazz.getDeclaredFields();
        Set<String> ignoreSet = new HashSet<>(Arrays.asList(ignoreProperties));
        for (Field field : fields) {
            if (!ignoreSet.contains(field.getName())) {
                try {
                    field.setAccessible(true);
                    Object temp = field.get(obj1);
                    field.set(obj1, field.get(obj2));
                    field.set(obj2, temp);
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    private static final Set<String> IGNORED_FIELDS = new HashSet<>(Arrays.asList("sVersion", "sId"));

    public static void swapProperties(Object obj1, Object obj2) {
        Class<?> clazz = obj1.getClass();
        Field[] fields = clazz.getDeclaredFields();
        for (Field field : fields) {
            if (!IGNORED_FIELDS.contains(field.getName()) && !field.isAnnotationPresent(IgnoreSwap.class)) {
                try {
                    field.setAccessible(true);
                    Object temp = field.get(obj1);
                    field.set(obj1, field.get(obj2));
                    field.set(obj2, temp);
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public static void copyProperties(Object source, Object target) {
        Class<?> clazz = source.getClass();
        Field[] fields = clazz.getDeclaredFields();
        for (Field field : fields) {
            if (!IGNORED_FIELDS.contains(field.getName()) && !field.isAnnotationPresent(IgnoreSwap.class)) {
                try {
                    field.setAccessible(true);
                    field.set(target, field.get(source));
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
